// 全局连接状态管理对象
const globalState = {
  isConnected: false,
  connecting: false,
  reconnectAttempts: 0,
  maxReconnectAttempts: 10,
  lastConnectTime: null,
  lastDisconnectTime: null
};

Page({
  // 页面数据
  data: {
    vbat: 0, // 最后电压
    warningVoltage: 0, // 警告电压
    warningType: 'none', // 警告类型: none, high, low
    hist: [],
    connected: false, // WebSocket连接状态
    connecting: false, // WebSocket连接中状态
    connectStatus: 'disconnected', // 连接状态: disconnected, connecting, connected, error
    mqttConnected: false, // MQTT连接状态
    chart: null,
    showDebug: false, // 控制调试日志显示
    debugLogs: [],
    // 图表缩放相关
    scale: 1,
    initialDistance: null,
    // WebSocket连接相关
    socketTask: null,
    // 连接状态控制
    isClosing: false,
    // 重连控制
    reconnectCount: 0,
    maxReconnectCount: 10,
    baseReconnectDelay: 1000,
    // 滚动控制
    debugScrollTop: 0,
    // 电压阈值配置
    voltageThresholds: {
      lower: 3.5,
      upper: 4.2
    },
    // 阈值显示属性
    lowThreshold: '3.500',
    highThreshold: '4.200',
    // 连接状态显示
    linkStatus: 'unknown',
    errorPoint: null,
    // 连接信息
    connectionInfo: {
      cloudHostingUrl: ''
    },
    // 云托管数据条数
    cloudDataCount: 0
  },

  onLoad: function() {
    try {
      // 初始化页面数据，确保包含voltageThresholds
      this.setData({
        vbat: 0,
        vbatUnit: 'V',
        connected: false,
        connecting: false,
        connectStatus: 'disconnected',
        mqttConnected: false,
        chartInit: false,
        debug: false,
        logs: [],
        cloudDataCount: 0,
        hist: [],
        // 确保初始化阈值配置
        voltageThresholds: {
          lower: 3.5,
          upper: 4.2
        }
      })

      // 获取全局配置
      const app = getApp();
      const cloudConfig = app.globalData.cloudConfig;
      const testMode = app.globalData.testMode || false;

      // 尝试从本地存储读取之前保存的阈值配置
      try {
        const storedParams = wx.getStorageSync('appParams');
        if (storedParams && storedParams.voltageThresholds) {
          const voltageThresholds = storedParams.voltageThresholds;
          this.setData({
            voltageThresholds: voltageThresholds,
            lowThreshold: voltageThresholds.lower ? voltageThresholds.lower.toFixed(3) : '3.500',
            highThreshold: voltageThresholds.upper ? voltageThresholds.upper.toFixed(3) : '4.200'
          });
          this.logDebug(`已从本地存储加载阈值配置: 下限=${voltageThresholds.lower}, 上限=${voltageThresholds.upper}`);
        }
      } catch (err) {
        console.error('读取本地存储的阈值配置失败:', err);
        this.logDebug('读取本地存储的阈值配置失败: ' + JSON.stringify(err));
      }

      // 保存重要参数到本地存储
      try {
        const paramsToSave = {
          cloudConfig: {
            env: cloudConfig.env,
            service: cloudConfig.service,
            appid: cloudConfig.appid,
            tid: cloudConfig.tid,
            rid: cloudConfig.rid,
            bid: cloudConfig.bid,
            instance: cloudConfig.instance,
            projectName: cloudConfig.projectName
          },
          testMode: testMode,
          voltageThresholds: this.data.voltageThresholds,
          lastUpdatedTime: new Date().getTime()
        };
        wx.setStorageSync('appParams', paramsToSave);
        this.logDebug('重要参数已保存到本地存储');
      } catch (err) {
        console.error('保存参数到本地存储失败:', err);
        this.logDebug('保存参数到本地存储失败: ' + JSON.stringify(err));
      }

      // 尝试从本地存储读取系统配置
      try {
        const storedSystemConfig = wx.getStorageSync('systemConfig');
        if (storedSystemConfig && (storedSystemConfig.maxHistorySize || storedSystemConfig.alertCooldownTime || storedSystemConfig.ALERT_COOLDOWN_TIME)) {
          // 兼容性处理：支持大写和小写命名的告警冷却时间
          const alertCooldownTime = storedSystemConfig.alertCooldownTime || storedSystemConfig.ALERT_COOLDOWN_TIME;
          const maxHistorySize = storedSystemConfig.maxHistorySize;
          
          // 创建标准化的配置对象，确保使用正确的命名格式
          const standardConfig = {
            alertCooldownTime: alertCooldownTime,
            maxHistorySize: maxHistorySize,
            // 保留原有配置的其他字段
            ...storedSystemConfig
          };
          
          this.systemConfig = standardConfig;
          // 设置到页面数据中，确保UI同步显示
          this.setData({
            systemConfig: standardConfig
          });
          this.logDebug(`已从本地存储加载系统配置: 最大历史记录=${maxHistorySize}, 告警冷却时间=${alertCooldownTime}`);
        }
      } catch (err) {
        console.error('读取本地存储的系统配置失败:', err);
        this.logDebug('读取本地存储的系统配置失败: ' + JSON.stringify(err));
      }

      // 读取本地存储的历史数据
      try {
        const storedHist = wx.getStorageSync('vbat_hist');
        if (storedHist && Array.isArray(storedHist)) {
          this.setData({
            hist: storedHist
          });
          this.logDebug(`已从本地存储加载${storedHist.length}条历史数据`);
          
          // 加载历史数据后，计算警告电压
          if (storedHist.length > 0) {
            const { warningVoltage, warningType } = this.getWarningVoltage(storedHist);
            const lastDataPoint = storedHist[storedHist.length - 1];
            
            this.setData({
              warningVoltage: warningVoltage,
              warningType: warningType,
              vbat: lastDataPoint.value // 设置最后一个电压值
            });
          }
        }
      } catch (err) {
        console.error('读取本地存储的历史数据失败:', err);
        this.logDebug('读取本地存储的历史数据失败: ' + JSON.stringify(err));
      }

      // 初始化图表
      this.initChart();

      // 连接WebSocket
      this.connectWebSocket();
      
      // 添加备用策略：如果WebSocket连接失败，3秒后再次尝试获取最新阈值配置和系统配置
      setTimeout(() => {
        if (!this.data.connected) {
          this.logDebug('WebSocket连接可能未成功，尝试通过requestThresholds获取最新阈值');
          this.requestThresholds();
          // 尝试获取系统配置
          this.requestSystemConfig();
          // 加载本地缓存数据作为备用
          this.loadLocalCacheData();
        }
      }, 3000);

    } catch (error) {
      console.error('onLoad发生错误:', error);
      this.logDebug('onLoad发生错误: ' + JSON.stringify(error));
    }
  },

  // 切换调试日志显示状态
  toggleDebug: function() {
    const newShowDebug = !this.data.showDebug;
    this.setData({
      showDebug: newShowDebug
    });
    this.logDebug(`调试日志已${newShowDebug ? '显示' : '隐藏'}`);
  },

  // 清空云托管历史数据
  clearCloudHistory: function() {
    wx.showModal({
      title: '确认清空',
      content: '确定要清空所有历史数据吗？此操作不可恢复。',
      success: (res) => {
        if (res.confirm) {
          this.logDebug('用户确认清空历史数据');
          this.setData({
            hist: []
          });
          wx.setStorageSync('vbat_hist', []);
          this.drawChart();
          this.logDebug('本地历史数据已清空');
          
          // 向服务器发送清空请求
          if (this.data.socketTask && this.data.connected) {
            this.data.socketTask.send({
              data: JSON.stringify({
                type: 'clear_history'
              }),
              success: () => {
                this.logDebug('已向服务器发送清空历史数据请求');
              },
              fail: (err) => {
                this.logDebug(`发送清空请求失败: ${JSON.stringify(err)}`);
              }
            });
          }
          
          wx.showToast({
            title: '历史数据已清空',
            icon: 'success'
          });
        }
      }
    });
  },



  // 记录调试日志
  logDebug: function(message) {
    const timestamp = new Date().toLocaleTimeString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false
    });
    
    let newLogs = [...this.data.debugLogs];
    // 将新消息添加到数组开头，而不是末尾
    newLogs.unshift(`${timestamp}: ${message}`);
    
    // 保持日志不超过100条
    if (newLogs.length > 100) {
      newLogs = newLogs.slice(0, 100);
    }
    
    this.setData({
      debugLogs: newLogs
      // 不再需要设置滚动到底部，因为最新消息已经在顶部
    });
  },
  onUnload: function() {
    // 页面卸载时断开WebSocket连接
    if (this.data.socketTask) {
      this.setData({
        isClosing: true
      });
      this.data.socketTask.close();
      this.setData({
        socketTask: null,
        isClosing: false
      });
    }
  },

  initChart: function() {
    // 使用Canvas 2D接口获取画布上下文
    const query = wx.createSelectorQuery().in(this);
    query.select('#vbatChart')
      .fields({
        node: true,
        size: true,
        rect: true
      })
      .exec((res) => {
        if (!res || res.length === 0) {
          console.error('获取canvas元素失败');
          return;
        }
        
        const canvas = res[0].node;
        const ctx = canvas.getContext('2d');
        
        // 获取实际容器尺寸
        const { width, height } = res[0];
        
        // 设置画布尺寸，确保与容器一致
        canvas.width = width;
        canvas.height = 350; // 高度保持350px
        
        // 保存canvas和上下文引用
        this.canvas = canvas;
        this.ctx = ctx;
        
        // 绘制初始图表，使用实际宽度
        this.drawChart(width);
      });
  },
  



  // 触摸开始事件
  onTouchStart: function(e) {
    if (e.touches.length === 2) {
      // 双指触摸开始，记录初始距离
      const x1 = e.touches[0].clientX;
      const y1 = e.touches[0].clientY;
      const x2 = e.touches[1].clientX;
      const y2 = e.touches[1].clientY;
      const distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
      this.setData({
        initialDistance: distance
      });
    }
  },
  
  // 触摸移动事件
  onTouchMove: function(e) {
    if (e.touches.length === 2) {
      // 双指触摸移动，计算缩放比例
      const x1 = e.touches[0].clientX;
      const y1 = e.touches[0].clientY;
      const x2 = e.touches[1].clientX;
      const y2 = e.touches[1].clientY;
      const newDistance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
      
      if (this.data.initialDistance) {
        const scaleFactor = newDistance / this.data.initialDistance;
        let newScale = this.data.scale * scaleFactor;
        
        // 限制缩放范围
        newScale = Math.max(1, Math.min(5, newScale));
        
        this.setData({
          scale: newScale,
          initialDistance: newDistance
        });
        
        // 重新绘制图表，使用canvas实际宽度
        if (this.canvas) {
          this.drawChart(this.canvas.width);
        }
      }
    }
  },
  
  // 触摸结束事件
  onTouchEnd: function() {
    this.setData({
      initialDistance: null
    });
  },
  
  drawChart: function(width) {
    if (!this.ctx || !this.canvas) {
      console.error('Canvas上下文未初始化');
      // 尝试重新初始化canvas
      if (!this.canvas) {
        this.initChart();
      }
      return;
    }
    
    const { hist, scale, voltageThresholds } = this.data;
    const ctx = this.ctx;
    const height = 350; // 高度保持350px
    const padding = 50; // 增加左侧padding以确保Y轴标签完全显示
    const chartW = width - padding * 2;
    const chartH = height - padding * 2;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 添加调试信息：显示当前阈值设置
    this.logDebug(`绘制图表: 阈值=${JSON.stringify(voltageThresholds)}, 历史数据点数量=${hist.length}`);
    
    // 确保hist是数组，如果不是则设为空数组
    const safeHist = Array.isArray(hist) ? hist : [];
    
    // 如果没有数据，绘制空图表状态
    if (safeHist.length === 0) {
      ctx.fillStyle = '#999';
      ctx.font = '14px sans-serif';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('暂无数据', width / 2, height / 2);
      return;
    }
    
    // 根据缩放比例确定显示的数据范围
    let displayHist = [...safeHist];
    if (scale > 1 && safeHist.length > 50) {
      const visiblePoints = Math.floor(safeHist.length / scale);
      const startIndex = Math.max(0, safeHist.length - visiblePoints);
      displayHist = safeHist.slice(startIndex);
    }
    
    // 添加调试信息：显示当前显示的数据点
    this.logDebug(`绘制图表: 显示的数据点数量=${displayHist.length}`);
    if (displayHist.length > 0) {
      this.logDebug(`绘制图表: 第一个数据点=${displayHist[0].value}V, 最后一个数据点=${displayHist[displayHist.length-1].value}V`);
    }
    
    // 计算显示数据的数据范围
    const values = displayHist.map(item => item && typeof item === 'object' && 'value' in item ? item.value : 0);
    const validValues = values.filter(v => !isNaN(v));
    let minVbat = Math.min(...validValues);
    let maxVbat = Math.max(...validValues);
    let vbatRange = maxVbat - minVbat || 0.5; // 防止range为0
    
    // 当所有值都相同时，人为增加范围以便更好地显示
    if (minVbat === maxVbat) {
      minVbat -= 0.25;
      maxVbat += 0.25;
      vbatRange = 0.5;
    }
    
    // 智能计算Y轴刻度
    // 1. 根据数据范围确定合适的刻度数量（每15-25像素一个刻度）
    const targetTickCount = Math.min(8, Math.max(3, Math.floor(chartH / 20)));
    
    // 2. 计算一个"漂亮"的刻度间距
    // 首先计算粗略间距
    let rawStep = vbatRange / (targetTickCount - 1);
    
    // 找到合适的十进制间距
    const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
    const normalized = rawStep / magnitude;
    
    // 选择一个合适的"漂亮"间距
    let step;
    if (normalized < 1.5) {
      step = magnitude;
    } else if (normalized < 3) {
      step = 2 * magnitude;
    } else if (normalized < 7.5) {
      step = 5 * magnitude;
    } else {
      step = 10 * magnitude;
    }
    
    // 3. 调整最小值和最大值以匹配这些"漂亮"的刻度
    const adjustedMin = Math.floor(minVbat / step) * step;
    const adjustedMax = Math.ceil(maxVbat / step) * step;
    
    // 4. 重新计算数据范围
    vbatRange = adjustedMax - adjustedMin;
    
    // 绘制坐标轴
    ctx.strokeStyle = '#eee';
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(padding, padding);
    ctx.lineTo(padding, height - padding);
    ctx.lineTo(width - padding, height - padding);
    ctx.stroke();
    
    // 绘制Y轴标签（电压值）
    ctx.fillStyle = '#999';
    ctx.font = '12px sans-serif';
    ctx.textAlign = 'right';
    ctx.textBaseline = 'middle';
    
    // 5. 根据调整后的刻度绘制Y轴
    const tickCount = Math.ceil(vbatRange / step) + 1;
    for (let i = 0; i < tickCount; i++) {
      const vbat = adjustedMin + i * step;
      // 计算对应的Y坐标（确保在有效范围内）
      const y = Math.max(padding, Math.min(height - padding, 
                    height - padding - ((vbat - adjustedMin) / vbatRange) * chartH));
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(padding - 5, y);
      ctx.lineTo(padding, y);
      ctx.stroke();
      
      // 绘制标签 - 增加左侧空间以确保完整显示
      // 始终显示3位小数
      const decimalPlaces = 3;
      // 增加padding的左侧空间，确保完整显示电压值
      ctx.fillText(vbat.toFixed(decimalPlaces) + 'V', padding - 5, y);
    }
    
    // 绘制阈值线
    if (voltageThresholds) {
      // 上阈值线
      const upperY = height - padding - ((voltageThresholds.upper - adjustedMin) / vbatRange) * chartH;
      if (upperY >= padding && upperY <= height - padding) {
        ctx.strokeStyle = '#ff9800';
        ctx.lineWidth = 1.5;
        ctx.setLineDash([5, 5]); // 虚线
        ctx.beginPath();
        ctx.moveTo(padding, upperY);
        ctx.lineTo(width - padding, upperY);
        ctx.stroke();
        
        // 上阈值标签
        ctx.fillStyle = '#ff9800';
        ctx.textAlign = 'left';
        ctx.fillText('上限: ' + voltageThresholds.upper.toFixed(3) + 'V', padding + 10, upperY - 10);
      }
      
      // 下阈值线
      const lowerY = height - padding - ((voltageThresholds.lower - adjustedMin) / vbatRange) * chartH;
      if (lowerY >= padding && lowerY <= height - padding) {
        ctx.strokeStyle = '#2196f3';
        ctx.lineWidth = 1.5;
        ctx.beginPath();
        ctx.moveTo(padding, lowerY);
        ctx.lineTo(width - padding, lowerY);
        ctx.stroke();
        
        // 下阈值标签
        ctx.fillStyle = '#2196f3';
        ctx.textAlign = 'left';
        ctx.fillText('下限: ' + voltageThresholds.lower.toFixed(3) + 'V', padding + 10, lowerY + 20);
      }
      
      // 重置线条样式
      ctx.setLineDash([]);
    }
    
    // 绘制X轴标签（时间）
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    
    // 计算需要显示的标签数量
    const labelCount = Math.min(5, displayHist.length);
    const labelStep = Math.max(1, Math.floor(displayHist.length / labelCount));
    
    for (let i = 0; i < displayHist.length; i += labelStep) {
      const x = padding + (i / (displayHist.length - 1)) * chartW;
      const date = new Date(displayHist[i].timestamp);
      const timeStr = date.getHours() + ':' + (date.getMinutes() < 10 ? '0' : '') + date.getMinutes();
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, height - padding);
      ctx.lineTo(x, height - padding + 5);
      ctx.stroke();
      
      // 绘制标签
      ctx.fillText(timeStr, x, height - padding + 8);
    }
    
    // 绘制曲线
    ctx.strokeStyle = '#07c160';
    ctx.lineWidth = 2;
    ctx.beginPath();
    
    // 存储超出阈值的点用于后续绘制红线和垂直线
    const outOfThresholdPoints = [];
    
    displayHist.forEach((dataPoint, index) => {
      const x = padding + (index / (displayHist.length - 1)) * chartW;
      // 使用调整后的最小值来计算Y坐标
      const y = height - padding - ((dataPoint.value - adjustedMin) / vbatRange) * chartH;
      
      // 确保Y坐标在有效范围内
      const clampedY = Math.max(padding, Math.min(height - padding, y));
      
      // 添加调试信息，记录坐标计算结果
      if (index === 0 || index === displayHist.length - 1) {
        this.logDebug(`数据点${index}: 值=${dataPoint.value}V, x=${x.toFixed(2)}, y=${y.toFixed(2)}, clampedY=${clampedY.toFixed(2)}`);
      }
      
      // 检查是否超出阈值
      if (dataPoint.value < voltageThresholds.lower || dataPoint.value > voltageThresholds.upper) {
        this.logDebug(`检测到超出阈值的数据点: 值=${dataPoint.value}V, 阈值下限=${voltageThresholds.lower}V, 阈值上限=${voltageThresholds.upper}V`);
        outOfThresholdPoints.push({
          x: x,
          y: clampedY,
          value: dataPoint.value,
          timestamp: dataPoint.timestamp,
          index: index
        });
      }
      
      if (index === 0) {
        ctx.moveTo(x, clampedY);
      } else {
        ctx.lineTo(x, clampedY);
      }
    });
    
    ctx.stroke();
    
    // 绘制超出阈值的点的红线和垂直线
    if (outOfThresholdPoints.length > 0) {
      this.logDebug(`绘制超出阈值的点: 数量=${outOfThresholdPoints.length}`);
      ctx.strokeStyle = '#e64340'; // 红色
      ctx.lineWidth = 2;
      
      outOfThresholdPoints.forEach(point => {
        // 绘制从点到时间轴的垂直线
        ctx.beginPath();
        ctx.moveTo(point.x, point.y);
        ctx.lineTo(point.x, height - padding);
        ctx.stroke();
        
        // 绘制红色圆点标记
        ctx.beginPath();
        ctx.arc(point.x, point.y, 4, 0, Math.PI * 2);
        ctx.fillStyle = '#e64340';
        ctx.fill();
        ctx.strokeStyle = '#fff';
        ctx.lineWidth = 1;
        ctx.stroke();
        
        // 在垂直线底部添加一个小箭头或标记
        ctx.beginPath();
        ctx.moveTo(point.x - 3, height - padding);
        ctx.lineTo(point.x, height - padding + 5);
        ctx.lineTo(point.x + 3, height - padding);
        ctx.fillStyle = '#e64340';
        ctx.fill();
        
        // 恢复红色描边样式
        ctx.strokeStyle = '#e64340';
        ctx.lineWidth = 2;
      });
    }
  },
  
  // 加载本地缓存数据作为备用
  loadLocalCacheData: function() {
    try {
      this.logDebug('开始加载本地缓存数据作为备用...');
      
      // 读取本地存储的历史数据
      const storedHist = wx.getStorageSync('vbat_hist');
      if (storedHist && Array.isArray(storedHist) && storedHist.length > 0) {
        this.setData({
          hist: storedHist,
          vbat: storedHist[storedHist.length - 1].value || 0
        });
        this.logDebug(`已加载${storedHist.length}条本地缓存的历史数据`);
        
        // 重新绘制图表显示本地数据
        if (this.canvas) {
          this.drawChart(this.canvas.width);
        } else {
          // 如果canvas还未初始化，使用windowWidth作为备用
          const { windowWidth } = wx.getWindowInfo();
          this.drawChart(windowWidth - 60);
        }
        
        // 显示已加载本地数据的提示
        wx.showToast({
          title: `已加载${storedHist.length}条本地缓存数据`,
          icon: 'info',
          duration: 2000
        });
        
        return true;
      } else {
        this.logDebug('本地没有可用的缓存历史数据');
      }
    } catch (error) {
      console.error('加载本地缓存数据失败:', error);
      this.logDebug('加载本地缓存数据失败: ' + JSON.stringify(error));
    }
    
    return false;
  },
  
  // 创建WebSocket连接
  connectWebSocket: async function() {
    // 获取全局配置和状态
    const app = getApp();
    // 确保connectionState对象已初始化
    if (!app.globalData.connectionState) {
      app.globalData.connectionState = {
        isConnected: false,
        connecting: false,
        lastConnectTime: 0,
        lastDisconnectTime: 0,
        reconnectAttempts: 0,
        maxReconnectAttempts: 10
      };
    }
    const globalState = app.globalData.connectionState;
    
    // 如果已经在连接中，则不再重复连接
    if (globalState.connecting) {
      this.logDebug('WebSocket连接正在进行中，取消重复连接请求');
      return;
    }
    
    // 标记正在连接中
    globalState.connecting = true;
    this.setData({
      connecting: true,
      connectStatus: 'connecting' // 连接中状态
    });
    
    // 关闭之前的连接（如果存在）
    if (this.data.socketTask) {
      this.setData({
        isClosing: true
      });
      this.data.socketTask.close();
      this.setData({
        socketTask: null,
        isClosing: false
      });
    }
    
    try {
      // 获取全局配置
      const cloudConfig = app.globalData.cloudConfig;
      const testMode = app.globalData.testMode || false;
      
      // 输出详细的配置信息用于调试
      this.logDebug('----- WebSocket连接配置信息 -----');
      this.logDebug(`testMode: ${testMode}`);
      this.logDebug(`cloudConfig.websocketUrl: ${cloudConfig.websocketUrl}`);
      this.logDebug(`cloudConfig.testWebsocketUrl: ${cloudConfig.testWebsocketUrl}`);
      this.logDebug(`cloudConfig.env: ${cloudConfig.env}`);
      this.logDebug(`cloudConfig.service: ${cloudConfig.service}`);
      this.logDebug(`cloudConfig.appid: ${cloudConfig.appid}`);
      this.logDebug(`cloudConfig.tid: ${cloudConfig.tid}`);
      this.logDebug(`cloudConfig.rid: ${cloudConfig.rid}`);
      this.logDebug(`cloudConfig.bid: ${cloudConfig.bid}`);
      this.logDebug(`cloudConfig.instance: ${cloudConfig.instance}`);
      this.logDebug(`cloudConfig.projectName: ${cloudConfig.projectName}`);
      
      let socketTask;
      
      // 创建连接超时Promise
      const connectionTimeout = new Promise((_, reject) => {
        setTimeout(() => reject(new Error('WebSocket连接超时')), 10000); // 10秒超时
      });
      
      // 根据测试模式动态选择连接方式
      if (testMode) {
        this.logDebug('使用测试模式WebSocket连接方式');
        // 测试模式: 使用本地ws协议直接连接
        const wsUrl = `${cloudConfig.testWebsocketUrl}/web_socket`;
        this.logDebug(`构建的测试WebSocket URL: ${wsUrl}`);
        
        // 使用Promise包装wx.connectSocket以支持超时处理
        const connectPromise = new Promise((resolve, reject) => {
          const task = wx.connectSocket({
          url: wsUrl,
          header: {
            'X-WX-SERVICE': cloudConfig.service,
            'X-WX-ENV': cloudConfig.env,
            'X-WX-APPID': cloudConfig.appid,
            'X-WX-TID': cloudConfig.tid,
            'X-WX-RID': cloudConfig.rid,
            'X-WX-BID': cloudConfig.bid
          },
          protocols: ['protocol1'],
          success: () => {
            console.log('测试模式WebSocket连接请求发送成功');
            setTimeout(() => resolve(task), 100); // 延迟一小段时间确保task已完全初始化
          },
          fail: (err) => {
            console.error('测试模式WebSocket连接请求发送失败:', err);
            this.logDebug('测试模式WebSocket连接请求发送失败: ' + JSON.stringify(err));
            reject(err);
          }
        });
        });
        
        // 使用Promise.race实现超时控制
        socketTask = await Promise.race([connectPromise, connectionTimeout]);
      } else {
          this.logDebug('使用生产模式云托管WebSocket连接方式');
          this.logDebug(`连接参数 - 服务: ${cloudConfig.service}, 环境: ${cloudConfig.env}`);
          
          // 生产模式: 使用wx.cloud.connectContainer方法，添加超时控制
          const connectPromise = new Promise((resolve, reject) => {
            wx.cloud.connectContainer({
            "config": {
              "env": cloudConfig.env
            },
            "service": cloudConfig.service,
            "path": "/",
              success: (res) => {
                this.logDebug('云托管WebSocket连接创建成功');
                resolve(res.socketTask);
              },
              fail: (error) => {
                this.logDebug('云托管WebSocket连接创建失败: ' + JSON.stringify(error));
                reject(error);
              }
            });
          });
          
          // 使用Promise.race实现超时控制
          socketTask = await Promise.race([connectPromise, connectionTimeout]);
        }
        
        if (!socketTask) {
          throw new Error('WebSocket连接返回null');
        }
        
        // 保存socket引用
      this.setData({
        socketTask: socketTask,
        connected: false
      });
      
      // 设置连接打开事件
      socketTask.onOpen(() => {
        this.logDebug('WebSocket连接已打开');
        
        // 更新连接状态
        this.setData({
          connected: true,
          connecting: false,
          connectStatus: 'connected' // 已连接状态
        });
        
        // 更新全局连接状态
        globalState.isConnected = true;
        globalState.connecting = false;
        globalState.lastConnectTime = new Date().getTime();
        globalState.reconnectAttempts = 0;
        
        // 显示连接成功提示
        wx.showToast({
          title: '已成功连接到服务器',
          icon: 'success',
          duration: 2000
        });
        
        // 发送上线通知
        this.sendOnlineNotification();
        
        // 请求所有配置数据，包含阈值信息
        this.getAllConfigs();
        
        // 自动获取历史数据，无需用户点击按钮
        this.getCloudHistory();
        
        // 请求系统配置（确保即使getAllConfigs没有返回完整系统配置也能获取）
        setTimeout(() => {
          this.requestSystemConfig();
        }, 1000);
      });
      
      // 设置消息接收事件
      socketTask.onMessage((res) => {
        try {
          const data = JSON.parse(res.data);
          
          // 处理不同类型的消息
          if (data.type === 'message' && data.topic) {
            this.handleWebSocketMessage(data.topic, data.payload);
          } else if (data.type === 'publish_response' || data.type === 'subscribe_response') {
            this.logDebug(`收到操作响应: ${data.type}, 成功: ${data.success}`);
          } else if (data.type === 'test_response') {
            this.handleWebSocketMessage('/robot/zack/vbat', JSON.stringify(data));
          } else if (data.type === 'heartbeat') {
            this.logDebug('收到心跳消息');
          } else if (data.type === 'mqtt_error' || data.type === 'mqtt_disconnected') {
            this.logDebug(`MQTT错误: ${JSON.stringify(data)}`);
            // 如果MQTT连接断开，设置错误位置
            this.setData({
              mqttConnected: false,
              linkStatus: 'error',
              errorPoint: 'cloud'
            });
          } else if (data.type === 'mqtt_connected') {
            this.logDebug('MQTT连接成功');
            this.setData({
              mqttConnected: true,
              linkStatus: 'ok',
              errorPoint: null
            });
          } else if (data.type === 'all_configs_updated') {
            // 直接处理所有配置更新消息
            this.handleWebSocketMessage('/config/update', data);
          } else if (data.type === 'system_config_updated') {
            // 处理系统配置更新消息
            this.logDebug('收到系统配置更新消息');
            if (data.newConfig) {
              // 兼容性处理：支持大写和小写命名的告警冷却时间
              const alertCooldownTime = data.newConfig.alertCooldownTime || data.newConfig.ALERT_COOLDOWN_TIME;
              const maxHistorySize = data.newConfig.maxHistorySize;
              
              // 更新系统配置并重新获取历史数据
              this.logDebug('系统配置已更新: 告警冷却时间=' + alertCooldownTime + 
                           ', 最大历史记录=' + maxHistorySize);
               
              // 保存系统配置到本地存储
              try {
                // 创建标准化的配置对象，确保使用正确的命名格式
                const standardConfig = {
                  alertCooldownTime: alertCooldownTime,
                  maxHistorySize: maxHistorySize,
                  // 保留原有配置的其他字段
                  ...data.newConfig
                };
                
                this.systemConfig = standardConfig;
                // 调用setData更新页面数据，确保UI同步更新
                this.setData({
                  systemConfig: standardConfig
                });
                wx.setStorageSync('systemConfig', standardConfig);
                this.logDebug('系统配置已保存到本地存储');
              } catch (err) {
                console.error('保存系统配置到本地存储失败:', err);
                this.logDebug('保存系统配置到本地存储失败: ' + JSON.stringify(err));
              }
               
              // 重新获取历史数据以应用新的最大历史记录限制
              this.getCloudHistory();
              // 显示配置更新成功提示
              wx.showToast({
                title: '系统配置已更新',
                icon: 'success',
                duration: 2000
              });
            }
          } else if (data.type === 'history_cleared') {
            // 处理历史数据清空成功的响应
            this.logDebug('历史数据已清空');
            // 清空本地历史数据
            this.setData({
              hist: [],
              vbat: 0
            });
            // 清空本地存储
            wx.removeStorageSync('vbat_hist');
            // 重新绘制图表
            const { windowWidth } = wx.getWindowInfo();
            this.drawChart(windowWidth - 60);
            // 显示获取成功提示，使用实际处理后的数据数量
            wx.showToast({
              title: `获取到${this.data.hist.length}条数据`,
              icon: 'success',
              duration: 2000
            });
          } else {
            // 处理未知类型消息
            this.handleUnknownMessageType(data);
          }
        } catch (error) {
          this.logDebug('解析WebSocket消息失败: ' + error.message);
        }
      });
      
      // 设置连接关闭事件
      socketTask.onClose(() => {
        this.logDebug('WebSocket连接已关闭');
        
        // 更新连接状态
        this.setData({
          connected: false,
          connecting: false,
          connectStatus: 'disconnected' // 已断开状态
        });
        
        // 更新全局连接状态
        globalState.isConnected = false;
        globalState.connecting = false;
        globalState.lastDisconnectTime = new Date().getTime();
        
        // 重连逻辑（带指数退避和重试次数限制）
        if (!this.data.isClosing) {
          // 显示连接断开提示
          if (globalState.reconnectAttempts === 0) {
            wx.showToast({
              title: '连接已断开，正在尝试重连',
              icon: 'none',
              duration: 3000
            });
          }
          
          globalState.reconnectAttempts++;
          
          if (globalState.reconnectAttempts <= globalState.maxReconnectAttempts) {
            // 计算退避延迟时间：基础时间 * (2^重连次数 - 1) + 随机抖动
            const baseDelay = 1000; // 1秒基础延迟
            const delay = baseDelay * (Math.pow(2, globalState.reconnectAttempts) - 1) + Math.random() * 1000;
            // 最大延迟不超过30秒
            const reconnectDelay = Math.min(delay, 30000);
            
            this.logDebug(`尝试重连WebSocket，第${globalState.reconnectAttempts}次，延迟${Math.round(reconnectDelay)}ms...`);
            setTimeout(() => {
              this.connectWebSocket();
            }, reconnectDelay);
          } else {
            this.logDebug(`已达到最大重连次数(${globalState.maxReconnectAttempts})，停止自动重连`);
            
            // 显示重连失败提示
            wx.showToast({
              title: '重连失败，请检查网络或稍后再试',
              icon: 'none',
              duration: 3000
            });
            
            // 加载本地缓存数据作为备用
            this.loadLocalCacheData();
          }
        }
      });
      
      // 设置连接错误事件
      socketTask.onError((error) => {
        const errorMsg = 'WebSocket连接发生错误: ' + JSON.stringify(error);
        console.error(errorMsg);
        this.logDebug(errorMsg);
        
        // 更新连接状态
        this.setData({
          connected: false,
          connecting: false,
          connectStatus: 'error' // 错误状态
        });
        
        // 更新全局连接状态
        globalState.isConnected = false;
        globalState.connecting = false;
        
        // 显示错误提示
        wx.showToast({
          title: '连接发生错误',
          icon: 'none',
          duration: 2000
        });
      });
    } catch (error) {
      const errorMsg = 'WebSocket连接失败: ' + JSON.stringify(error);
      console.error(errorMsg);
      this.logDebug(errorMsg);
      this.setData({ connected: false });
      
      // 检查错误是否与域名相关
      if (error && error.errMsg && error.errMsg.includes('url not in domain list')) {
        this.logDebug('错误提示：请检查小程序后台的域名配置，确保已添加正确的WebSocket域名');
      }
    }
  },

  // 处理接收到的WebSocket消息
  handleWebSocketMessage: function(topic, payload) {
    this.logDebug(`接收到主题为${topic}的消息`);
    if (topic === '/robot/zack/vbat') {
      try {
        // 增强解析能力：预处理数据，处理可能的格式问题
        let data;
        
        // 1. 首先检查数据类型，如果已经是对象则直接使用
        if (typeof payload === 'object' && payload !== null) {
          this.logDebug('数据已经是对象，直接使用');
          data = payload;
        } else {
          let processedPayload = payload;
          
          // 2. 处理可能的外层引号问题（常见于JSON嵌套）
          if (typeof processedPayload === 'string' && 
              processedPayload.startsWith('"') && processedPayload.endsWith('"')) {
            try {
              // 尝试去除外层引号并解析
              processedPayload = processedPayload.slice(1, -1);
              // 处理转义字符（如果有）
              processedPayload = processedPayload.replace(/\\"/g, '"');
            } catch (e) {
              this.logDebug('去除外层引号时出错: ' + e.message);
            }
          }
          
          // 3. 尝试标准JSON解析
          data = JSON.parse(processedPayload);
          this.logDebug(`解析数据成功: ${typeof data === 'object' ? JSON.stringify(data) : data}`);
        }
        
        // 4. 处理解析后的数据
        this.parseAndProcessData(data);
      } catch (error) {
        const errorMsg = '解析数据失败: ' + error.message;
        console.error(errorMsg);
        this.logDebug(errorMsg);
        
        // 增强的备用解析逻辑
        try {
          if (typeof payload === 'string' && payload.length > 0) {
            this.logDebug(`原始消息内容: ${payload}`);
            
            // 尝试将字符串作为数组元素处理
            if (payload.startsWith('[') && payload.endsWith(']')) {
              try {
                const arrayData = JSON.parse(payload);
                if (Array.isArray(arrayData) && arrayData.length > 0) {
                  this.logDebug(`成功解析为数组，包含${arrayData.length}个元素`);
                  // 处理数组中的每个元素
                  arrayData.forEach((item, index) => {
                    try {
                      this.parseAndProcessData(item);
                    } catch (itemError) {
                      this.logDebug(`处理数组元素${index}失败: ${itemError.message}`);
                    }
                  });
                  return;
                }
              } catch (e) {
                this.logDebug(`尝试解析为数组失败: ${e.message}`);
              }
            }
            
            // 检查是否包含数字字符串（可能是电压值）
            const numMatches = payload.match(/\d+(\.\d+)?/);
            if (numMatches && numMatches.length > 0) {
              const potentialVoltage = parseFloat(numMatches[0]);
              if (!isNaN(potentialVoltage)) {
                this.logDebug(`尝试从原始字符串中提取电压数据: ${potentialVoltage}`);
                // 创建临时数据对象并处理
                const tempData = { value: potentialVoltage };
                this.parseAndProcessData(tempData);
              }
            }
          }
        } catch (fallbackError) {
          this.logDebug(`备用解析方法也失败: ${fallbackError.message}`);
        }
      }
    } else if (topic === '/config/update') {
      // 处理配置更新消息
      try {
        const data = payload;
        this.logDebug(`处理配置更新消息: ${JSON.stringify(data)}`);
        
        // 更新阈值数据
        // 首先尝试直接从payload中获取，如果不存在则尝试从payload.data中获取
        let voltageThresholdsData = null;
        if (data.voltageThresholds && typeof data.voltageThresholds === 'object') {
          voltageThresholdsData = data.voltageThresholds;
        } else if (data.data && data.data.voltageThresholds && typeof data.data.voltageThresholds === 'object') {
          voltageThresholdsData = data.data.voltageThresholds;
        }
        
        if (voltageThresholdsData) {
          this.setData({
            voltageThresholds: voltageThresholdsData,
            lowThreshold: voltageThresholdsData.lower ? voltageThresholdsData.lower.toFixed(3) : '3.500',
            highThreshold: voltageThresholdsData.upper ? voltageThresholdsData.upper.toFixed(3) : '4.200'
          });
          this.logDebug(`阈值已更新: 下限=${voltageThresholdsData.lower}, 上限=${voltageThresholdsData.upper}`);
          
          // 保存更新后的阈值到本地存储
          try {
            const storedParams = wx.getStorageSync('appParams') || {};
            storedParams.voltageThresholds = voltageThresholdsData;
            storedParams.lastUpdatedTime = new Date().getTime();
            wx.setStorageSync('appParams', storedParams);
            this.logDebug('阈值配置已保存到本地存储');
          } catch (err) {
            console.error('保存阈值到本地存储失败:', err);
            this.logDebug('保存阈值到本地存储失败: ' + JSON.stringify(err));
          }
          
          // 重新绘制图表以更新阈值线
          const { windowWidth } = wx.getWindowInfo();
          this.drawChart(windowWidth - 60);
          
          // 重新计算警告电压
          const { warningVoltage, warningType } = this.getWarningVoltage(this.data.hist);
          this.setData({
            warningVoltage: warningVoltage,
            warningType: warningType
          });
        }
        
      } catch (error) {
        this.logDebug(`处理配置更新消息失败: ${error.message}`);
      }
    } else {
      this.logDebug(`忽略非目标主题${topic}的消息`);
    }
  },

  // 增强的数据解析处理函数，支持多种数据格式
  parseAndProcessData: function(data, isHistoricalData = false) {
    // 处理带单位的电压值的辅助函数
    const parseVoltageValue = function(value) {
      if (typeof value === 'number') return value;
      if (typeof value !== 'string') return NaN;
      
      // 尝试去除可能的单位（如V或mV）并转换为数字
      // 提取数字部分（包括小数点和正负号）
      const match = value.match(/[-+]?\d*\.?\d+/);
      if (match) {
        let numValue = parseFloat(match[0]);
        
        // 检查是否需要单位转换（如果包含mV，转换为V）
        if (value.toLowerCase().includes('mv') && numValue > 10) {
          numValue = numValue / 1000;
        }
        
        return numValue;
      }
      return NaN;
    };
    
    // 检查数据是否为数组格式
    if (Array.isArray(data)) {
      this.logDebug("处理数组格式数据，共" + data.length + "个元素");
      // 处理数组中的每个元素
      data.forEach((item, index) => {
        try {
          this.logDebug("处理数组元素" + (index+1) + "/" + data.length);
          this.parseAndProcessData(item, isHistoricalData);
        } catch (itemError) {
          this.logDebug("处理数组元素" + index + "失败: " + itemError.message);
        }
      });
      return;
    }
    
    // 特殊处理: 检测"originalData"嵌套对象格式（从调试日志中观察到的数据格式）
    if (data.originalData && typeof data.originalData === 'object') {
    this.logDebug('检测到originalData嵌套对象格式');
    const originalData = data.originalData;
    let processedCount = 0;
    
    // 检查originalData是否直接包含voltage字段
    try {
      // 直接从originalData中提取电压值
      let itemVoltage = null;
      
      // 尝试从originalData中提取电压数据
      // 使用parseVoltageValue函数处理可能带单位的电压值
      if (originalData.vbat !== undefined) {
        itemVoltage = parseVoltageValue(originalData.vbat);
        this.logDebug("从originalData.vbat字段提取电压数据: " + itemVoltage);
      } else if (originalData.voltage !== undefined) {
        itemVoltage = parseVoltageValue(originalData.voltage);
        this.logDebug("从originalData.voltage字段提取电压数据: " + itemVoltage);
      } else if (originalData.value !== undefined) {
        itemVoltage = parseVoltageValue(originalData.value);
        this.logDebug("从originalData.value字段提取电压数据: " + itemVoltage);
      }
      
      // 如果提取到有效电压值，直接添加到历史记录
      if (itemVoltage !== null && !isNaN(itemVoltage)) {
        // 处理单位转换
        if (itemVoltage > 1000) {
          itemVoltage = itemVoltage / 1000;
          this.logDebug("单位转换: " + (itemVoltage * 1000) + "mV -> " + itemVoltage + "V");
        }
        
        // 获取时间戳
        const timestamp = originalData.timestamp ? new Date(originalData.timestamp).getTime() : new Date().getTime();
        
        // 添加到历史记录，根据type判断是否为告警
        const isAlarm = originalData.type === 'test_alert';
        this.logDebug(`准备从originalData添加数据点: 值=${itemVoltage.toFixed(3)}V, 时间戳=${timestamp}, isAlarm=${isAlarm}`);
        this.addHist(itemVoltage, timestamp, isAlarm);
        processedCount++;
      }
    } catch (itemError) {
      this.logDebug("处理originalData失败: " + itemError.message);
    }
    this.logDebug("成功处理" + processedCount + "条originalData数据");
    
    // 在处理完所有originalData后，重新计算警告电压并更新UI
    if (processedCount > 0 && !isHistoricalData) {
      const warningData = this.getWarningVoltage(this.data.hist);
      this.setData({
        warningVoltage: warningData.warningVoltage,
        warningType: warningData.warningType
      });
    }
    
    // 检查电压字段（vbat或voltage）
    let vbatValue = null;
    
    // 尝试从常见字段中获取电压数据 - 使用更清晰的逻辑
    const voltageFields = ['v', 'vbat', 'voltage', 'value'];
    
    // 首先检查顶层字段
    for (const field of voltageFields) {
      if (data[field] !== undefined) {
        vbatValue = parseVoltageValue(data[field]);
        if (!isNaN(vbatValue)) {
          this.logDebug("从" + field + "字段获取电压数据: " + vbatValue);
          break;
        }
      }
    }
    
    // 如果顶层没有找到，检查嵌套对象
    if (vbatValue === null || isNaN(vbatValue)) {
      // 检查payload嵌套对象
      if (data.payload && typeof data.payload === 'object') {
        for (const field of voltageFields) {
          if (data.payload[field] !== undefined) {
            vbatValue = parseVoltageValue(data.payload[field]);
            if (!isNaN(vbatValue)) {
              this.logDebug("从payload." + field + "字段获取电压数据: " + vbatValue);
              break;
            }
          }
        }
      }
      
      // 如果仍未找到，检查data嵌套对象
      if (vbatValue === null || isNaN(vbatValue)) {
        if (data.data && typeof data.data === 'object') {
          for (const field of voltageFields) {
            if (data.data[field] !== undefined) {
              vbatValue = parseVoltageValue(data.data[field]);
              if (!isNaN(vbatValue)) {
                this.logDebug("从data." + field + "字段获取电压数据: " + vbatValue);
                break;
              }
            }
          }
        }
      }
    }
    
    // 增强的数据有效性检查
    if (vbatValue !== null && !isNaN(vbatValue)) {
      // 检查数值是否在合理范围内（0-50V）
      if (vbatValue > 50) {
        // 可能是毫伏单位
        this.logDebug("检测到可能为毫伏单位数据: " + vbatValue + "mV，转换为伏特");
        vbatValue = vbatValue / 1000;
      } else if (vbatValue <= 0) {
        // 电压值应该是正数，记录异常值但继续处理
        this.logDebug("警告: 检测到异常电压值: " + vbatValue + "V");
      }
      
      // 二次检查转换后的数值是否合理
      if (vbatValue < 0 || vbatValue > 50) {
        this.logDebug("警告: 转换后电压值" + vbatValue + "V超出合理范围，可能数据异常");
      }
      
      this.logDebug("处理后电压值: " + vbatValue.toFixed(3) + "V" + (isHistoricalData ? " (历史数据)" : ""));
      
      // 添加到历史记录，确保使用数据原始时间戳
      // 检查是否是测试告警模式的数据，用于正确设置isAlarm标志
      const isAlarm = data.originalData && data.originalData.type === 'test_alert';
      this.logDebug(`准备添加数据点: 值=${vbatValue.toFixed(3)}V, 时间戳=${data.timestamp || new Date().getTime()}, isAlarm=${isAlarm}`);
      this.addHist(vbatValue, data.timestamp || new Date().getTime(), isAlarm);
    }
    
    // 专门处理电压阈值数据
    // 情况1: 处理VOLTAGE_THRESHOLDS对象
    if (data.VOLTAGE_THRESHOLDS && typeof data.VOLTAGE_THRESHOLDS === 'object') {
      const thresholds = data.VOLTAGE_THRESHOLDS;
      if (thresholds.lower !== undefined && thresholds.upper !== undefined) {
        this.logDebug("接收到电压阈值数据: 下限=" + thresholds.lower + ", 上限=" + thresholds.upper);
        // 更新电压阈值
        this.setData({
          voltageThresholds: thresholds
        });
        // 重新计算警告电压
        const warningData = this.getWarningVoltage(this.data.hist);
        this.setData({
          warningVoltage: warningData.warningVoltage,
          warningType: warningData.warningType
        });
        // 重新绘制图表，使阈值线反映新的阈值
        const windowWidth = wx.getWindowInfo().windowWidth;
        this.drawChart(windowWidth - 60);
        // 记录到调试日志但不显示Toast提示，避免频繁提示
        this.logDebug('电压阈值已更新');
      }
    } 
    // 情况2: 处理type为set_thresholds的消息（直接在顶层包含lower和upper字段）
    else if (data.type === 'set_thresholds' && data.lower !== undefined && data.upper !== undefined) {
      this.logDebug("接收到set_thresholds消息: 下限=" + data.lower + ", 上限=" + data.upper);
      // 更新电压阈值，同时更新页面上显示的阈值
      this.setData({
        voltageThresholds: {
          lower: data.lower,
          upper: data.upper
        },
        lowThreshold: data.lower.toFixed(3),
        highThreshold: data.upper.toFixed(3)
      });
      // 重新计算警告电压
      const warningData = this.getWarningVoltage(this.data.hist);
      this.setData({
        warningVoltage: warningData.warningVoltage,
        warningType: warningData.warningType
      });
      // 重新绘制图表，使阈值线反映新的阈值
      const windowWidth = wx.getWindowInfo().windowWidth;
      this.drawChart(windowWidth - 60);
      // 记录到调试日志
      this.logDebug('电压阈值已更新(set_thresholds消息)');
    }
    // 情况3: 处理系统配置更新消息（包含alertCooldownTime或maxHistorySize字段）
    else if ((data.type === 'set_system_config' && (data.alertCooldownTime !== undefined || data.maxHistorySize !== undefined)) ||
             ((typeof data.alertCooldownTime === 'number' || typeof data.maxHistorySize === 'number') &&
              data.type !== 'set_thresholds' && !data.VOLTAGE_THRESHOLDS)) {
      this.logDebug("接收到系统配置更新消息: 告警冷却时间=" + data.alertCooldownTime + ", 最大历史记录=" + data.maxHistorySize);
      
      // 保存系统配置到本地存储
      try {
        this.systemConfig = {
          ALERT_COOLDOWN_TIME: data.alertCooldownTime || (this.systemConfig && this.systemConfig.ALERT_COOLDOWN_TIME),
          maxHistorySize: data.maxHistorySize || (this.systemConfig && this.systemConfig.maxHistorySize)
        };
        wx.setStorageSync('systemConfig', this.systemConfig);
        this.logDebug('系统配置已保存到本地存储');
      } catch (err) {
        console.error('保存系统配置到本地存储失败:', err);
        this.logDebug('保存系统配置到本地存储失败: ' + JSON.stringify(err));
      }
      
      // 重新获取历史数据以应用新的最大历史记录限制
      this.getCloudHistory();
      
      // 显示配置更新成功提示
      wx.showToast({
        title: '系统配置已更新',
        icon: 'success',
        duration: 2000
      });
    } else if (Object.keys(data).length > 0) {
      // 解析其他可能的字段，记录到日志但不影响主流程
      const extraFields = {};
      for (const key in data) {
        // 跳过已经处理过的字段
        if (!['vbat', 'voltage', 'value', 'type', 'timestamp', 'clientId', 'VOLTAGE_THRESHOLDS'].includes(key)) {
          extraFields[key] = data[key];
        }
      }
      
      if (Object.keys(extraFields).length > 0) {
        this.logDebug("检测到其他数据字段: " + JSON.stringify(extraFields));
      }
    }
  }
  },
  
  // 处理未知类型消息
  handleUnknownMessageType: function(data) {
    switch(data.type) {
      case 'system_config_update_response':
        // 处理系统配置更新响应
        this.logDebug(`系统配置更新响应: ${data.message || '未知状态'}`);
        
        // 特别处理"正在处理"的状态（优先判断，即使success为true）
        if (data.message && data.message.includes('正在处理')) {
          wx.showLoading({
            title: '配置更新中...',
            mask: true
          });
          // 5秒后自动隐藏加载提示，防止卡死在加载状态
          setTimeout(() => {
            wx.hideLoading();
          }, 5000);
        } else if (data.success) {
          wx.hideLoading();
          wx.showToast({
            title: '设置成功',
            icon: 'success',
            duration: 2000
          });
        } else {
          wx.hideLoading();
          wx.showToast({
            title: '设置失败',
            icon: 'none',
            duration: 2000
          });
        }
        break;
        
      case 'system_config_save_response':
        // 处理系统配置保存确认消息（从MQTT客户端接收的专门回复）
        this.logDebug(`系统配置保存确认: ${data.message || '未知状态'}`);
        
        // 隐藏任何可能存在的加载提示
        wx.hideLoading();
        
        if (data.success) {
          // 显示保存成功的提示
          wx.showToast({
            title: '设置保存成功',
            icon: 'success',
            duration: 2000
          });
          
          // 如果消息中包含更新后的配置，应用它
          if (data.updatedConfig && typeof data.updatedConfig === 'object') {
            this.logDebug('从确认消息中获取更新后的配置');
            try {
              // 保存系统配置到本地存储
              this.systemConfig = data.updatedConfig;
              wx.setStorageSync('systemConfig', data.updatedConfig);
              
              // 更新页面数据
              this.setData({
                systemConfig: data.updatedConfig
              });
              
              // 如果有最大历史记录限制，应用它
              if (data.updatedConfig.maxHistorySize) {
                this.logDebug('将应用新的最大历史记录限制: ' + data.updatedConfig.maxHistorySize);
                // 重新获取历史数据以应用新的最大历史记录限制
                this.getCloudHistory();
              }
            } catch (err) {
              console.error('保存系统配置到本地存储失败:', err);
              this.logDebug('保存系统配置到本地存储失败: ' + JSON.stringify(err));
            }
          }
        } else {
          wx.showToast({
            title: data.message || '设置保存失败',
            icon: 'none',
            duration: 2000
          });
        }
        break;
        
      case 'system_config_updated':
        // 处理系统配置已更新的消息（从云托管通过WebSocket直接发送）
        if (data.success && data.newConfig) {
          this.logDebug(`收到系统配置已更新消息: ${JSON.stringify(data.newConfig)}`);
          
          // 首先隐藏任何可能存在的加载提示
          wx.hideLoading();
          
          // 保存系统配置到本地存储
          try {
            this.systemConfig = data.newConfig;
            wx.setStorageSync('systemConfig', data.newConfig);
            this.logDebug('系统配置已保存到本地存储');
            
            // 如果有最大历史记录限制，应用它
            if (data.newConfig.maxHistorySize) {
              this.logDebug('将应用新的最大历史记录限制: ' + data.newConfig.maxHistorySize);
              // 重新获取历史数据以应用新的最大历史记录限制
              this.getCloudHistory();
            }
            
            // 显示配置更新成功提示
            wx.showToast({
              title: '系统配置已更新',
              icon: 'success',
              duration: 2000
            });
          } catch (err) {
            console.error('保存系统配置到本地存储失败:', err);
            this.logDebug('保存系统配置到本地存储失败: ' + JSON.stringify(err));
            wx.showToast({
              title: '配置保存失败',
              icon: 'none',
              duration: 2000
            });
          }
        } else {
          this.logDebug(`系统配置更新通知格式错误: ${JSON.stringify(data)}`);
        }
        break;
      
      case 'connection_established':
        this.logDebug('MQTT连接已建立');
        this.setData({
          mqttConnected: true,
          linkStatus: 'ok',
          errorPoint: null
        });
        break;
        
      case 'connect':
        // MQTT连接成功消息
        if (data.success) {
          this.logDebug(`MQTT连接成功，服务器: ${data.broker || 'unknown'}`);
          this.setData({
            mqttConnected: true,
            linkStatus: 'ok',
            errorPoint: null
          });
        } else {
          this.logDebug(`MQTT连接失败: ${data.message || '未知错误'}`);
          this.setData({
            mqttConnected: false,
            linkStatus: 'error',
            errorPoint: 'mqtt'
          });
        }
        break;
        
      case 'error':
        // 处理云服务返回的错误消息
        const errorMessage = data.message || '未知错误';
        this.logDebug(`收到云服务错误消息: ${errorMessage}`);
        
        // 记录错误详情，但不立即改变连接状态，因为这个可能是临时错误
        if (data.error) {
          this.logDebug(`错误详情: ${data.error}`);
        }
        break;
        
      case 'cloud_data_count':
        // 处理云数据条数响应
        this.logDebug(`收到云数据条数: ${data.count}`);
        this.setData({
          cloudDataCount: data.count || 0
        });
        break;
        
      case 'cloud_data_update':
        // 处理云数据更新响应
        this.logDebug('收到云数据更新');
        if (data.data && Array.isArray(data.data)) {
          this.logDebug(`收到 ${data.data.length} 条新数据`);
          // 处理新数据 - 实时数据，允许发送告警
          data.data.forEach(item => {
            try {
              this.parseAndProcessData(item, false);
            } catch (error) {
              this.logDebug(`处理单条数据失败: ${error.message}`);
            }
          });
        }
        break;
        
      // 处理历史数据响应
      case 'history_data':
        // 处理历史数据响应
        this.logDebug(`收到历史数据，共 ${data.totalRecords || 0} 条`);
        // 无论数据是否为空，先清空现有历史数据
        this.setData({ hist: [] });
        if (data.data && Array.isArray(data.data) && data.data.length > 0) {
          // 处理所有历史数据，确保数据格式正确
          const validHistoryData = data.data.filter(item => item && typeof item === 'object' && (item.vbat !== undefined || item.voltage !== undefined || item.value !== undefined));
          
          if (validHistoryData.length > 0) {
            this.logDebug(`处理 ${validHistoryData.length} 条有效历史数据`);
            validHistoryData.forEach(item => {
              try {
                // 处理历史数据 - 不发送告警
                this.parseAndProcessData(item, true);
              } catch (error) {
                this.logDebug(`处理历史数据项失败: ${error.message}`);
              }
            });
            
            // 手动重新计算警告电压，确保所有数据处理完毕后正确更新
            const { warningVoltage, warningType } = this.getWarningVoltage(this.data.hist);
            this.setData({
              warningVoltage: warningVoltage,
              warningType: warningType
            });
            
            // 更新本地存储
            wx.setStorageSync('vbat_hist', this.data.hist);
            // 强制延迟一小段时间确保数据已完全更新，然后重新绘制图表
            setTimeout(() => {
              // 重新绘制图表
              if (this.canvas) {
                this.drawChart(this.canvas.width);
              } else {
                const { windowWidth } = wx.getWindowInfo();
                this.drawChart(windowWidth - 60);
              }
            }, 100);
            // 显示获取成功提示，使用实际处理后的数据数量
            wx.showToast({
              title: `获取到${this.data.hist.length}条数据`,
              icon: 'success',
              duration: 2000
            });
          } else {
            this.logDebug('未找到有效历史数据');
            wx.showToast({
              title: '无有效数据',
              icon: 'none',
              duration: 2000
            });
          }
        } else {
          this.logDebug('历史数据为空或格式不正确');
          // 强制延迟一小段时间确保数据已完全更新，然后重新绘制图表
          setTimeout(() => {
            // 重新绘制图表以反映空数据状态
            if (this.canvas) {
              this.drawChart(this.canvas.width);
            } else {
              const { windowWidth } = wx.getWindowInfo();
              this.drawChart(windowWidth - 60);
            }
          }, 100);
          // 清除本地存储中的历史数据
          try {
            wx.removeStorageSync('vbat_hist');
            this.logDebug('本地存储中的历史数据已清除');
          } catch (err) {
            console.error('清除本地存储历史数据失败:', err);
          }
          wx.showToast({
            title: '无历史数据',
            icon: 'none',
            duration: 2000
          });
        }
        break;
        
      case 'alarm_received':
        // 处理云服务返回的告警确认消息
        if (data.success) {
          this.logDebug(`告警确认已收到: ${data.alertType || 'unknown'}类型，电压${data.voltage || 'unknown'}`);
          // 显示提示
          wx.showToast({
            title: '告警已发送',
            icon: 'success',
            duration: 3000
          });
        } else {
          this.logDebug(`告警发送失败: ${data.message || '未知错误'}`);
          // 显示提示
          wx.showToast({
            title: '告警发送失败',
            icon: 'none',
            duration: 3000
          });
        }
        break;
        
      case 'thresholds_updated':
        // 处理阈值更新消息
        if (data.data && typeof data.data === 'object' && data.success) {
          this.logDebug(`收到阈值更新: 下限=${data.data.lower}, 上限=${data.data.upper}`);
          // 更新电压阈值数据
          this.setData({
            voltageThresholds: data.data
          });
          
          // 重新计算警告电压
          const { warningVoltage, warningType } = this.getWarningVoltage(this.data.hist);
          this.setData({
            warningVoltage: warningVoltage,
            warningType: warningType
          });
          
          // 保存更新后的阈值到本地存储
          try {
            const storedParams = wx.getStorageSync('appParams') || {};
            storedParams.voltageThresholds = data.data;
            storedParams.lastUpdatedTime = new Date().getTime();
            wx.setStorageSync('appParams', storedParams);
            this.logDebug('阈值配置已保存到本地存储');
          } catch (err) {
            console.error('保存阈值到本地存储失败:', err);
            this.logDebug('保存阈值到本地存储失败: ' + JSON.stringify(err));
          }
          
          // 重新绘制图表，使阈值线反映新的阈值
          const { windowWidth } = wx.getWindowInfo();
          this.drawChart(windowWidth - 60);
          // 显示阈值更新成功的提示
          wx.showToast({
            title: '电压阈值已更新',
            icon: 'success',
            duration: 2000
          });
        } else {
          this.logDebug(`阈值更新失败: ${data.message || '未知错误'}`);
          wx.showToast({
            title: '阈值更新失败',
            icon: 'none',
            duration: 2000
          });
        }
        break;
        
      case 'all_configs_updated':
        // 处理所有配置更新消息
        let configData = {};
        // 支持两种数据格式：data.data嵌套格式 和 直接配置对象格式
        if (data.data && typeof data.data === 'object') {
          configData = data.data;
        } else if (data.voltageThresholds && data.systemConfig) {
          // 直接使用配置对象格式（从云托管直接获取的格式）
          configData = data;
          this.logDebug('检测到直接配置对象格式');
        }
        
        if (Object.keys(configData).length > 0) {
          this.logDebug('收到所有配置更新消息');
          
          // 更新阈值数据
          if (configData.voltageThresholds && typeof configData.voltageThresholds === 'object') {
            this.setData({
              voltageThresholds: configData.voltageThresholds
            });
            this.logDebug(`阈值已更新: 下限=${configData.voltageThresholds.lower}, 上限=${configData.voltageThresholds.upper}`);
            
            // 保存更新后的阈值到本地存储
            try {
              const storedParams = wx.getStorageSync('appParams') || {};
              storedParams.voltageThresholds = configData.voltageThresholds;
              storedParams.lastUpdatedTime = new Date().getTime();
              wx.setStorageSync('appParams', storedParams);
              this.logDebug('阈值配置已保存到本地存储');
            } catch (err) {
              console.error('保存阈值到本地存储失败:', err);
              this.logDebug('保存阈值到本地存储失败: ' + JSON.stringify(err));
            }
            
            // 重新绘制图表以更新阈值线
            const { windowWidth } = wx.getWindowInfo();
            this.drawChart(windowWidth - 60);
            
            // 重新计算警告电压
            const { warningVoltage, warningType } = this.getWarningVoltage(this.data.hist);
            this.setData({
              warningVoltage: warningVoltage,
              warningType: warningType
            });
          }
          
          // 更新钉钉机器人配置
          if (configData.dingtalkRobot) {
            this.logDebug('钉钉机器人配置: webhook=' + (configData.dingtalkRobot.webhook ? '已设置' : '未设置') + 
                          ', keywords=' + (configData.dingtalkRobot.keywords ? configData.dingtalkRobot.keywords.join(', ') : '无'));
            // 可以在这里保存钉钉机器人配置到本地缓存
          } else if (configData.hasDingtalkWebhook !== undefined || configData.dingtalkKeywords) {
            // 处理直接从云托管获取的格式
            this.logDebug('钉钉机器人配置: webhook=' + (configData.hasDingtalkWebhook ? '已设置' : '未设置') + 
                          ', keywords=' + (configData.dingtalkKeywords ? configData.dingtalkKeywords.join(', ') : '无'));
          }
          
          // 更新系统配置
          if (configData.systemConfig) {
            this.logDebug('系统配置: 告警冷却时间=' + (configData.systemConfig.ALERT_COOLDOWN_TIME || '默认') + 
                          ', 最大历史记录=' + (configData.systemConfig.maxHistorySize || '默认'));
            // 保存系统配置到本地存储
            try {
              this.systemConfig = configData.systemConfig;
              wx.setStorageSync('systemConfig', configData.systemConfig);
              this.logDebug('系统配置已保存到本地存储');
              // 如果有最大历史记录限制，应用它
              if (configData.systemConfig.maxHistorySize) {
                this.logDebug('将应用新的最大历史记录限制: ' + configData.systemConfig.maxHistorySize);
                // 重新获取历史数据以应用新的最大历史记录限制
                this.getCloudHistory();
              }
            } catch (err) {
              console.error('保存系统配置到本地存储失败:', err);
              this.logDebug('保存系统配置到本地存储失败: ' + JSON.stringify(err));
            }
          }
          
          // 更新数据条数信息
          if (configData.dataCounts) {
            const dataCounts = configData.dataCounts;
            this.logDebug('数据统计: 最近电压数据条数=' + dataCounts.recentVoltageDataCount + 
                          ', 重要消息条数=' + dataCounts.importantMessagesCount + 
                          ', 设备登录记录数=' + dataCounts.deviceLoginRecordsCount + 
                          ', 最大历史记录=' + dataCounts.maxHistorySize);
            
            // 更新页面数据统计信息
            this.setData({
              dataCounts: dataCounts
            });
            
            // 显示数据条数更新成功的提示
            wx.showToast({
              title: `数据条数已更新: ${dataCounts.recentVoltageDataCount}条`,
              icon: 'none',
              duration: 2000
            });
          }
          
          this.logDebug('所有配置数据已更新');
        } else {
          this.logDebug('配置数据格式错误: ' + JSON.stringify(data));
        }
        break;
        
      default:
        this.logDebug(`收到未处理的消息类型: ${data.type}`);
    }
  },

  // 发送发布消息到云托管服务
  sendPublish: function(topic, payload, options = {}) {
    if (this.data.socketTask && this.data.connected) {
      try {
        const messageToSend = JSON.stringify({
          type: 'publish',
          topic: topic,
          payload: payload,
          options: options
        });
        
        console.log(`准备发送消息到主题 ${topic}，内容: ${messageToSend.substring(0, 100)}${messageToSend.length > 100 ? '...' : ''}`);
        
        this.data.socketTask.send({
          data: messageToSend,
          success: () => {
            console.log(`消息成功发送到主题 ${topic}`);
          },
          fail: (error) => {
            console.log(`发送消息失败: ${JSON.stringify(error)}`);
          },
          complete: () => {
            console.log(`发送消息到主题 ${topic} 操作完成`);
          }
        });
      } catch (error) {
        console.log(`发送消息异常: ${JSON.stringify(error)}`);
      }
    } else {
      console.log(`WebSocket未连接，无法发送消息 (socketTask: ${this.data.socketTask ? '存在' : '不存在'}, connected: ${this.data.connected})`);
    }
  },



  // 发送订阅请求到云托管服务
  sendSubscribe: function(topic, options = {}) {
    if (this.data.socketTask && this.data.connected) {
      try {
        this.data.socketTask.send({
          data: JSON.stringify({
            type: 'subscribe',
            topic: topic,
            options: options
          }),
          success: () => {
            this.logDebug(`请求订阅主题 ${topic}`);
          },
          fail: (error) => {
            this.logDebug(`发送订阅请求失败: ${JSON.stringify(error)}`);
          }
        });
      } catch (error) {
        this.logDebug(`发送订阅请求异常: ${JSON.stringify(error)}`);
      }
    } else {
      this.logDebug('WebSocket未连接，无法订阅主题');
    }
  },
  
  // 从云托管获取历史数据
  getCloudHistory: function() {
    if (!this.data.connected || !this.data.socketTask) {
      this.logDebug('WebSocket未连接，无法获取历史数据');
      return;
    }
    
    const message = JSON.stringify({
      type: 'get_history'
    });
    
    this.data.socketTask.send({
      data: message,
      success: () => {
        this.logDebug('成功发送获取历史数据请求');
      },
      fail: (err) => {
        this.logDebug(`发送获取历史数据请求失败: ${err.errMsg}`);
      }
    });
  },
  
  // 请求云数据条数
  requestCloudDataCount: function() {
    if (!this.data.connected || !this.data.socketTask) {
      this.logDebug('WebSocket未连接，无法请求云数据条数');
      return;
    }
    
    const message = JSON.stringify({
      type: 'get_data_count'
    });
    
    this.data.socketTask.send({
      data: message,
      success: () => {
        this.logDebug('成功发送请求云数据条数请求');
      },
      fail: (err) => {
        this.logDebug(`发送请求云数据条数请求失败: ${err.errMsg}`);
      }
    });
  },


  
  // 请求最新的阈值设置
  requestThresholds: function() {
    try {
      this.logDebug('请求最新的阈值设置');
      if (this.data.socketTask && this.data.connected) {
        this.data.socketTask.send({
          data: JSON.stringify({
            type: 'get_thresholds'
          }),
          success: () => {
            this.logDebug('阈值请求已发送');
          },
          fail: (err) => {
            this.logDebug('发送阈值请求失败: ' + JSON.stringify(err));
          }
        });
      }
    } catch (error) {
      this.logDebug('请求阈值时发生错误: ' + JSON.stringify(error));
    }
  },
  
  // 请求所有配置数据
  getAllConfigs: function() {
    try {
      this.logDebug('请求所有配置数据');
      if (this.data.socketTask && this.data.connected) {
        this.data.socketTask.send({
          data: JSON.stringify({
            type: 'get_all_configs'
          }),
          success: () => {
            this.logDebug('所有配置数据请求已发送');
          },
          fail: (err) => {
            this.logDebug('发送配置数据请求失败: ' + JSON.stringify(err));
          }
        });
      }
    } catch (error) {
      this.logDebug('请求配置数据时发生错误: ' + JSON.stringify(error));
    }
  },
  
  // 请求最新的系统配置
  requestSystemConfig: function() {
    try {
      this.logDebug('请求最新的系统配置');
      if (this.data.socketTask && this.data.connected) {
        this.data.socketTask.send({
          data: JSON.stringify({
            type: 'get_system_config'
          }),
          success: () => {
            this.logDebug('系统配置请求已发送');
          },
          fail: (err) => {
            this.logDebug('发送系统配置请求失败: ' + JSON.stringify(err));
            // 发送失败时尝试使用备用方法获取配置
            this.fetchCloudHostingConfigFromAPI();
          }
        });
      } else {
        // WebSocket未连接时，尝试通过HTTP API获取配置
        this.fetchCloudHostingConfigFromAPI();
      }
    } catch (error) {
      this.logDebug('请求系统配置时发生错误: ' + JSON.stringify(error));
      // 发生异常时尝试使用备用方法获取配置
      this.fetchCloudHostingConfigFromAPI();
    }
  },
  
  // 通过HTTP API获取云托管配置（备用方法）
  fetchCloudHostingConfigFromAPI: function() {
    try {
      this.logDebug('尝试通过HTTP API获取云托管配置');
      const app = getApp();
      const cloudConfig = app.globalData.cloudConfig;
      
      wx.cloud.callContainer({
        "config": {
          "env": cloudConfig.env
        },
        "path": "/api/config",
        "header": {
          "X-WX-SERVICE": cloudConfig.service,
          "content-type": "application/json"
        },
        "method": "GET",
        success: (res) => {
          if (res.statusCode === 200 && res.data && res.data.status === 'ok' && res.data.config && res.data.config.SYSTEM_CONFIG) {
            this.logDebug('通过HTTP API获取云托管配置成功');
            
            // 获取原始系统配置
            const originalConfig = res.data.config.SYSTEM_CONFIG;
            
            // 兼容性处理：支持大写和小写命名的告警冷却时间
            const alertCooldownTime = originalConfig.alertCooldownTime || originalConfig.ALERT_COOLDOWN_TIME;
            const maxHistorySize = originalConfig.maxHistorySize;
            
            // 创建标准化的配置对象，确保使用正确的命名格式
            const standardConfig = {
              alertCooldownTime: alertCooldownTime,
              maxHistorySize: maxHistorySize,
              // 保留原有配置的其他字段
              ...originalConfig
            };
            
            // 更新系统配置
            this.systemConfig = standardConfig;
            // 调用setData更新页面数据，确保UI同步更新
            this.setData({
              systemConfig: standardConfig
            });
            
            // 保存到本地存储
            wx.setStorageSync('systemConfig', standardConfig);
            this.logDebug('系统配置已保存到本地存储: 告警冷却时间=' + alertCooldownTime + 
                         ', 最大历史记录=' + maxHistorySize);
            
            // 显示配置更新成功提示
            wx.showToast({
              title: '系统配置已更新',
              icon: 'success',
              duration: 2000
            });
          }
        },
        fail: (error) => {
          this.logDebug('通过HTTP API获取云托管配置失败: ' + JSON.stringify(error));
        }
      });
    } catch (error) {
      this.logDebug('调用HTTP API时发生错误: ' + JSON.stringify(error));
    }
  },
  
  // 发送上线通知到云托管
  sendOnlineNotification: function() {
    if (!this.data.connected || !this.data.socketTask) {
      console.log('WebSocket未连接，无法发送上线通知');
      return;
    }
    
    // 注意：使用与链路测试消息相同的格式发送上线通知
    // 这样才能确保消息被正确路由到MQTT broker
    const onlineMessage = JSON.stringify({
      type: 'publish',
      topic: '/robot/zack/vbat',
      payload: JSON.stringify({
        type: 'online_notification',
        timestamp: new Date().toISOString()
      })
    });
    
    this.logDebug('准备发送上线通知');
    this.data.socketTask.send({
      data: onlineMessage,
      success: () => {
        this.logDebug('成功发送上线通知到云托管');
        console.log('成功发送上线通知到云托管');
      },
      fail: (err) => {
        this.logDebug(`发送上线通知失败: ${err.errMsg}`);
        console.log(`发送上线通知失败: ${err.errMsg}`);
      },
    });
  },

  // 清空云托管历史数据
  clearCloudHistory: function() {
    // 显示确认弹窗
    wx.showModal({
      title: '确认清空',
      content: '确定要清空所有历史数据吗？此操作不可恢复。',
      success: (res) => {
        if (res.confirm) {
          if (!this.data.connected || !this.data.socketTask) {
            this.logDebug('WebSocket未连接，无法清空历史数据');
            wx.showToast({
              title: '未连接，无法清空',
              icon: 'none'
            });
            return;
          }
          
          const message = JSON.stringify({
            type: 'clear_history'
          });
          
          this.data.socketTask.send({
            data: message,
            success: () => {
              this.logDebug('成功发送清空历史数据请求');
            },
            fail: (err) => {
              this.logDebug(`发送清空历史数据请求失败: ${err.errMsg}`);
              wx.showToast({
                title: '发送请求失败',
                icon: 'none'
              });
            }
          });
        }
      }
    });
  },

  // 获取警告电压（警告最高的或最低的）
  getWarningVoltage: function(hist) {
    // 检查历史数据数组是否有效
    if (!hist || !Array.isArray(hist) || hist.length === 0) {
      this.logDebug('getWarningVoltage: 无效的历史数据');
      return { warningVoltage: 0, warningType: 'none' };
    }
    
    // 确保阈值是有效的数字，如果不是则使用默认值
    let lower = 3.5;
    let upper = 4.2;
    
    try {
      if (this.data.voltageThresholds && typeof this.data.voltageThresholds === 'object') {
        if (typeof this.data.voltageThresholds.lower === 'number' && !isNaN(this.data.voltageThresholds.lower)) {
          lower = this.data.voltageThresholds.lower;
        }
        if (typeof this.data.voltageThresholds.upper === 'number' && !isNaN(this.data.voltageThresholds.upper)) {
          upper = this.data.voltageThresholds.upper;
        }
      }
    } catch (err) {
      this.logDebug('获取阈值时发生错误: ' + err.message);
    }
    
    // 过滤出有效的电压值
    const validVoltages = [];
    for (const point of hist) {
      // 尝试从不同格式的数据点中提取电压值
      let value;
      if (point && typeof point.value === 'number') {
        value = point.value;
      } else if (point && typeof point.vbat === 'number') {
        value = point.vbat;
      } else if (point && typeof point.voltage === 'number') {
        value = point.voltage;
      } else if (point && typeof point.V === 'number') {
        value = point.V;
      } else if (typeof point === 'number' && !isNaN(point)) {
        value = point;
      }
      
      if (typeof value === 'number' && !isNaN(value)) {
        validVoltages.push(value);
      }
    }
    
    // 如果没有有效的电压值，返回默认值
    if (validVoltages.length === 0) {
      this.logDebug('getWarningVoltage: 没有有效的电压数据');
      return { warningVoltage: 0, warningType: 'none' };
    }
    
    // 找出低于阈值的最小值和高于阈值的最大值
    const lowerThanThreshold = validVoltages.filter(v => v < lower);
    const higherThanThreshold = validVoltages.filter(v => v > upper);
    
    // 初始化返回值
    let warningVoltage = 0;
    let warningType = 'none';
    
    // 如果有低于阈值的数据，显示其中的最小值
    if (lowerThanThreshold.length > 0) {
      warningVoltage = Math.min(...lowerThanThreshold);
      warningType = 'low';
    } 
    // 如果有高于阈值的数据，显示其中的最大值
    else if (higherThanThreshold.length > 0) {
      warningVoltage = Math.max(...higherThanThreshold);
      warningType = 'high';
    } 
    // 如果没有超过阈值的数据，显示最后一个数据点的电压
    else {
      // 获取最后一个数据点
      const lastDataPoint = hist[hist.length - 1];
      
      // 尝试从最后一个数据点提取电压值
      if (lastDataPoint && typeof lastDataPoint.value === 'number') {
        warningVoltage = lastDataPoint.value;
      } else if (lastDataPoint && typeof lastDataPoint.vbat === 'number') {
        warningVoltage = lastDataPoint.vbat;
      } else if (lastDataPoint && typeof lastDataPoint.voltage === 'number') {
        warningVoltage = lastDataPoint.voltage;
      } else if (lastDataPoint && typeof lastDataPoint.V === 'number') {
        warningVoltage = lastDataPoint.V;
      } else if (typeof lastDataPoint === 'number' && !isNaN(lastDataPoint)) {
        warningVoltage = lastDataPoint;
      } else {
        // 如果最后一个数据点也无效，使用有效电压数组中的最后一个值
        warningVoltage = validVoltages[validVoltages.length - 1];
      }
      
      warningType = 'none';
    }
    
    // 确保返回的warningVoltage是有效数字
    if (typeof warningVoltage !== 'number' || isNaN(warningVoltage)) {
      warningVoltage = 0;
      warningType = 'none';
    }
    
    this.logDebug(`getWarningVoltage: 警告电压=${warningVoltage}, 类型=${warningType}, 阈值=[${lower}, ${upper}]`);
    return { warningVoltage, warningType };
  },
  
  // 添加历史数据点
  addHist: function(value, timestamp = new Date().getTime(), isAlarm = false) {
    // 检查输入参数有效性
    if (typeof value !== 'number' || isNaN(value)) {
      this.logDebug(`addHist: 无效的电压值 ${value}`);
      return;
    }
    
    try {
      let hist = [...this.data.hist];
      
      // 添加新数据点（包含时间戳和告警标记）
      const dataPoint = {
        value: value,
        timestamp: timestamp,
        isAlarm: isAlarm
      };
      hist.push(dataPoint);
      
      // 获取最大历史记录数，默认为200
      const maxHistorySize = this.systemConfig && typeof this.systemConfig.maxHistorySize === 'number' && this.systemConfig.maxHistorySize > 0 ? 
                              this.systemConfig.maxHistorySize : 200;
                              
      // 限制历史数据数量
      if (hist.length > maxHistorySize) {
        hist = hist.slice(hist.length - maxHistorySize);
      }
      
      this.logDebug(`应用历史记录限制: 当前${hist.length}条，最大${maxHistorySize}条`);
      
      // 获取警告电压
      const { warningVoltage, warningType } = this.getWarningVoltage(hist);
      
      // 更新数据和显示
      this.setData({ 
        hist,
        vbat: value, // 保留最后电压值
        warningVoltage: warningVoltage, // 警告电压值
        warningType: warningType // 警告类型
      });
      
      // 保存到本地存储
      try {
        wx.setStorageSync('vbat_hist', hist);
        this.logDebug(`addHist: 历史数据已保存到本地存储，当前共有${hist.length}条`);
      } catch (storageErr) {
        this.logDebug(`addHist: 保存历史数据到本地存储失败: ${storageErr.message}`);
      }
      
      // 重新绘制图表
      try {
        if (this.canvas) {
          this.drawChart(this.canvas.width);
        } else {
          // 如果canvas还未初始化，使用windowWidth作为备用
          const { windowWidth } = wx.getWindowInfo();
          this.drawChart(windowWidth - 60);
        }
      } catch (chartErr) {
        this.logDebug(`addHist: 绘制图表失败: ${chartErr.message}`);
      }
      
    } catch (error) {
      this.logDebug(`addHist: 处理数据点失败: ${error.message}`);
    }
  },

  // 日志记录函数
  logDebug: function(message) {
    const timestamp = new Date().toLocaleTimeString('zh-CN', {
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit',
      hour12: false
    });
    
    let newLogs = [...this.data.debugLogs];
    // 将新消息添加到数组开头，而不是末尾
    newLogs.unshift(`${timestamp}: ${message}`);
    
    // 保持日志不超过100条
    if (newLogs.length > 100) {
      newLogs = newLogs.slice(0, 100);
    }
    
    this.setData({
      debugLogs: newLogs
      // 不再需要设置滚动到底部，因为最新消息已经在顶部
    });
    
    // 同时输出到控制台
    console.log(`${timestamp}: ${message}`);
  },
  
  // 格式化时间戳为可读时间
  formatTime: function(timestamp) {
    if (!timestamp) return '';
    const date = new Date(timestamp);
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    const seconds = String(date.getSeconds()).padStart(2, '0');
    
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }
});